#include "snowboy/snowboy-detect-c-wrapper.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "record.h"
#include "stt.h"
#include "chat.h"
#include "config.h"
#include "http.h"

#define SILENCE_THRESHOLD 2 // 静音持续时间阈值（秒）

void handle_error(const char *message, snd_pcm_t *capture, SnowboyDetect *detector) {
    perror(message);
    if (capture) {
        record_close(capture);
    }
    if (detector) {
        SnowboyDetectDestructor(detector);
    }
    exit(EXIT_FAILURE);
}

int main() {
    // 创建snowboy检测器
    SnowboyDetect* detector = SnowboyDetectConstructor("common.res", "model.pmdl");
    if (!detector) {
        return EXIT_FAILURE;
    }

    // 获取检测器支持的音频数据参数
    int bits = SnowboyDetectBitsPerSample(detector);
    int channels = SnowboyDetectNumChannels(detector);
    int rate = SnowboyDetectSampleRate(detector);

    printf("采样深度: %d\n", bits);
    printf("声道数量: %d\n", channels);
    printf("采样频率: %d\n", rate);

    // 打开音频采集设备
    snd_pcm_uframes_t period = 999;
    snd_pcm_t* capture = record_open("hw:0,0", SND_PCM_FORMAT_S16_LE, channels, rate, &period);
    if (!capture) {
        SnowboyDetectDestructor(detector);
        return EXIT_FAILURE;
    }

    char* buffer = malloc(snd_pcm_frames_to_bytes(capture, period)); // 分配缓冲区
    if (!buffer) {
        handle_error("malloc", capture, detector);
    }

    int recording = 0; // 录音状态标志
    time_t silence_start = 0; // 静音开始时间
    FILE* pcm_file = NULL; // 内存文件
    char* audio = NULL; // 音频缓冲区
    size_t audio_size = 0; // 音频大小

    // 读取配置文件中的平台密钥
    cJSON* config = read_config("config.json");
    if (!config) {
        handle_error("读取配置文件失败", capture, detector);
    }

    cJSON* authtoken = cJSON_GetObjectItem(config, "authtoken");
    if (!authtoken) {
        fprintf(stderr, "配置文件错误: 找不到 'authtoken' 字段\n");
        cJSON_Delete(config);
        handle_error("配置文件错误", capture, detector);
    }

    // 创建会话
    char* conv_id = create_conversation(authtoken->valuestring);
    if (!conv_id) {
        handle_error("创建会话失败", capture, detector);
    }

    printf("conv_id: %s\n", conv_id);

    while (1) {
        snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据
        if (frames < 0) {
            fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
            snd_pcm_recover(capture, frames, 0);
            continue;
        }

        int status = SnowboyDetectRunDetection(detector, (int16_t*)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0);

        if (status > 0) { // 检测到唤醒词
            if (!recording) {
                printf("检测到唤醒词，开始录音\n");
                recording = 1; // 开始录音
                silence_start = 0; // 重置静音计时
                pcm_file = open_memstream(&audio, &audio_size); // 打开内存文件
                if (!pcm_file) {
                    handle_error("open_memstream", capture, detector);
                }
            }
        }

        if (recording) {
            if (status == -2) { // 静音
                if (silence_start == 0) {
                    silence_start = time(NULL); // 记录静音开始时间
                } else if (time(NULL) - silence_start >= SILENCE_THRESHOLD) {
                    printf("静音超过2秒，停止录音\n");
                    recording = 0; // 停止录音
                    silence_start = 0; // 重置静音计时
                    fclose(pcm_file); // 关闭内存文件
                    pcm_file = NULL;

                    if (audio_size > 0) {
                        // 暂停录音
                        snd_pcm_drop(capture);
                        // 识别语音
                        char* text = speech_to_text(audio, audio_size);
                        if (text) {
                            puts(text);
                            // 调用百度云千帆AppBuilder API进行对话
                            char* answer = chat(authtoken->valuestring, conv_id, text);
                            if (answer) {
                                printf("< %s\n", answer);
                                free(answer);
                            }
                            free(text);
                        }
                        free(audio);
                        audio = NULL;
                        audio_size = 0;
                        // 恢复录音
                        snd_pcm_prepare(capture);
                    }
                }
            } else { // 有声音或唤醒词
                silence_start = 0; // 重置静音计时
            }

            if (pcm_file) {
                fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, pcm_file); // 将读取的数据写入内存文件
            }
        }
    }

    free(buffer);
    record_close(capture);
    SnowboyDetectDestructor(detector);

    return EXIT_SUCCESS;
}
